var _typeof =
  typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol'
    ? function (obj) {
        return typeof obj
      }
    : function (obj) {
        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj
      }

function FormatParams() {}

FormatParams.prototype.getData = function (data) {
  var str = ''
  var first = true
  var that = this
  if (!this.isObject(data)) {
    return data
  }

  function _encode(sub, path) {
    var encode = that.encode
    var type = that.type(sub)
    if (type == 'array') {
      sub.forEach(function (e, i) {
        if (!that.isObject(e)) i = ''
        _encode(e, path + ('%5B' + i + '%5D'))
      })
    } else if (type == 'object') {
      for (var key in sub) {
        if (path) {
          _encode(sub[key], path + '%5B' + encode(key) + '%5D')
        } else {
          _encode(sub[key], encode(key))
        }
      }
    } else {
      if (!first) {
        str += '&'
      }
      first = false
      str += path + '=' + encode(sub)
    }
  }

  _encode(data, '')
  return str
}

FormatParams.prototype.encode = function (val) {
  return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']')
}

FormatParams.prototype.isObject = function (ob, real) {
  if (real) {
    return this.type(ob) === 'object'
  } else {
    return ob && (typeof ob === 'undefined' ? 'undefined' : _typeof(ob)) === 'object'
  }
}

FormatParams.prototype.type = function type(ob) {
  return Object.prototype.toString.call(ob).slice(8, -1).toLowerCase()
}

let fp = new FormatParams()

console.log(fp.getData({
  str: '123',
  obj: {
    a: 1
  }
}))
console.log(decodeURIComponent(fp.getData([123, {a:456}, 789])))
